<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AuditLuma 报告生成器</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
        rel="stylesheet">
    <script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
    <style>
        /* Reset and Base Styles */
        *,
        *::before,
        *::after {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        :root {
            /* Exact color system from your Next.js app */
            --background: 0 0% 100%;
            --foreground: 222.2 84% 4.9%;
            --card: 0 0% 100%;
            --card-foreground: 222.2 84% 4.9%;
            --popover: 0 0% 100%;
            --popover-foreground: 222.2 84% 4.9%;
            --primary: 222.2 47.4% 11.2%;
            --primary-foreground: 210 40% 98%;
            --secondary: 210 40% 96.1%;
            --secondary-foreground: 222.2 47.4% 11.2%;
            --muted: 210 40% 96.1%;
            --muted-foreground: 215.4 16.3% 46.9%;
            --accent: 210 40% 96.1%;
            --accent-foreground: 222.2 47.4% 11.2%;
            --destructive: 0 84.2% 60.2%;
            --destructive-foreground: 210 40% 98%;
            --border: 214.3 31.8% 91.4%;
            --input: 214.3 31.8% 91.4%;
            --ring: 222.2 84% 4.9%;
            --radius: 0.5rem;

            /* Additional semantic colors matching your dashboard */
            --success: 142.1 76.2% 36.3%;
            --success-foreground: 210 40% 98%;
            --warning: 32.5 94.6% 43.7%;
            --warning-foreground: 210 40% 98%;
            --info: 217.2 91.2% 59.8%;
            --info-foreground: 210 40% 98%;

            /* Gray scale matching Tailwind used in dashboard */
            --gray-50: 210 40% 98%;
            --gray-100: 210 40% 96%;
            --gray-200: 214.3 31.8% 91.4%;
            --gray-300: 213 27% 84%;
            --gray-400: 215 20.2% 65.1%;
            --gray-500: 215.4 16.3% 46.9%;
            --gray-600: 215 19% 35%;
            --gray-700: 215 25% 27%;
            --gray-800: 217 33% 17%;
            --gray-900: 222.2 84% 4.9%;
        }

        .dark {
            --background: 222.2 84% 4.9%;
            --foreground: 210 40% 98%;
            --card: 222.2 84% 4.9%;
            --card-foreground: 210 40% 98%;
            --popover: 222.2 84% 4.9%;
            --popover-foreground: 210 40% 98%;
            --primary: 210 40% 98%;
            --primary-foreground: 222.2 47.4% 11.2%;
            --secondary: 217.2 32.6% 17.5%;
            --secondary-foreground: 210 40% 98%;
            --muted: 217.2 32.6% 17.5%;
            --muted-foreground: 215 20.2% 65.1%;
            --accent: 217.2 32.6% 17.5%;
            --accent-foreground: 210 40% 98%;
            --destructive: 0 62.8% 30.6%;
            --destructive-foreground: 210 40% 98%;
            --border: 217.2 32.6% 17.5%;
            --input: 217.2 32.6% 17.5%;
            --ring: 212.7 26.8% 83.9%;
        }

        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
            color: hsl(var(--foreground));
            line-height: 1.5;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            min-height: 100vh;
            position: relative;
        }

        /* 背景装饰 - 参考登录页面和首页 */
        body::before {
            content: '';
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
            z-index: -3;
        }

        body::after {
            content: '';
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 20% 50%, rgba(99, 102, 241, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 40% 80%, rgba(59, 130, 246, 0.08) 0%, transparent 50%);
            z-index: -2;
        }

        /* 网格装饰 */
        .bg-grid {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-image:
                linear-gradient(rgba(99, 102, 241, 0.03) 1px, transparent 1px),
                linear-gradient(90deg, rgba(99, 102, 241, 0.03) 1px, transparent 1px);
            background-size: 20px 20px;
            z-index: -1;
        }

        /* Layout Components */
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 1.5rem;
        }

        .page-header {
            margin-bottom: 2rem;
        }

        .page-title {
            font-size: 2.5rem;
            font-weight: 800;
            background: linear-gradient(135deg, #1e293b 0%, #6366f1 50%, #8b5cf6 100%);
            background-clip: text;
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            margin-bottom: 0.75rem;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 1rem;
            text-align: center;
            letter-spacing: -0.025em;
            position: relative;
        }

        .page-title::after {
            content: '';
            position: absolute;
            bottom: -8px;
            left: 50%;
            transform: translateX(-50%);
            width: 60px;
            height: 3px;
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
            border-radius: 2px;
            opacity: 0.6;
        }

        .page-title i {
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
            background-clip: text;
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            filter: drop-shadow(0 2px 4px rgba(99, 102, 241, 0.2));
        }

        .page-description {
            color: #64748b;
            font-size: 1.125rem;
            text-align: center;
            font-weight: 400;
            max-width: 600px;
            margin: 0 auto;
        }

        /* Card Components - 匹配登录页面的现代卡片设计 */
        .card {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(20px);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 1.5rem;
            box-shadow:
                0 20px 25px -5px rgba(0, 0, 0, 0.1),
                0 10px 10px -5px rgba(0, 0, 0, 0.04),
                0 0 0 1px rgba(255, 255, 255, 0.05);
            transition: all 300ms ease;
        }

        .card:hover {
            transform: translateY(-2px);
            box-shadow:
                0 25px 50px -12px rgba(0, 0, 0, 0.15),
                0 20px 25px -5px rgba(0, 0, 0, 0.1),
                0 0 0 1px rgba(255, 255, 255, 0.1);
        }

        .card-header {
            padding: 1.5rem;
            border-bottom: 1px solid hsl(var(--border));
        }

        .card-title {
            font-size: 1.25rem;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .card-content {
            padding: 1.5rem;
        }

        /* Button Components - 匹配登录页面的渐变按钮样式 */
        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
            border-radius: 0.75rem;
            font-size: 0.875rem;
            font-weight: 600;
            transition: all 300ms ease;
            cursor: pointer;
            border: none;
            text-decoration: none;
            white-space: nowrap;
            position: relative;
            overflow: hidden;
        }

        .btn-primary {
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #06b6d4 100%);
            color: white;
            padding: 0.75rem 1.5rem;
            box-shadow: 0 4px 14px 0 rgba(99, 102, 241, 0.3);
        }

        .btn-primary:hover:not(:disabled) {
            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #0891b2 100%);
            transform: translateY(-2px);
            box-shadow: 0 8px 25px 0 rgba(99, 102, 241, 0.4);
        }

        .btn-secondary {
            background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
            color: #475569;
            border: 2px solid #e2e8f0;
            padding: 0.75rem 1.5rem;
        }

        .btn-secondary:hover:not(:disabled) {
            background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
            border-color: #cbd5e1;
            transform: translateY(-1px);
        }

        .btn-outline {
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(10px);
            color: #475569;
            border: 2px solid #e2e8f0;
            padding: 0.75rem 1.5rem;
        }

        .btn-outline:hover:not(:disabled) {
            background: rgba(255, 255, 255, 0.95);
            border-color: #6366f1;
            color: #6366f1;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(99, 102, 241, 0.15);
        }

        .btn-ghost {
            background: transparent;
            color: #64748b;
            padding: 0.75rem 1.5rem;
        }

        .btn-ghost:hover:not(:disabled) {
            background: rgba(99, 102, 241, 0.1);
            color: #6366f1;
        }

        .btn:disabled {
            opacity: 0.4;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }

        .btn-sm {
            padding: 0.5rem 1rem;
            font-size: 0.75rem;
        }

        .btn-lg {
            padding: 1rem 2rem;
            font-size: 1rem;
        }

        /* Input Components - 匹配登录页面的现代输入框设计 */
        .input {
            display: flex;
            width: 100%;
            border-radius: 0.75rem;
            border: 2px solid #e2e8f0;
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(10px);
            padding: 0.75rem 1rem;
            font-size: 0.875rem;
            font-weight: 400;
            color: #1e293b;
            transition: all 300ms ease;
        }

        .input:focus {
            outline: none;
            border-color: #6366f1;
            background: rgba(255, 255, 255, 0.95);
            box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
            transform: translateY(-1px);
        }

        .input:hover {
            border-color: #cbd5e1;
        }

        .input::placeholder {
            color: #64748b;
            font-weight: 400;
        }

        .select {
            display: flex;
            width: 100%;
            border-radius: 0.75rem;
            border: 2px solid #e2e8f0;
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(10px);
            padding: 0.75rem 1rem;
            font-size: 0.875rem;
            font-weight: 500;
            color: #1e293b;
            cursor: pointer;
            transition: all 300ms ease;
        }

        .select:focus {
            outline: none;
            border-color: #6366f1;
            background: rgba(255, 255, 255, 0.95);
            box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
            transform: translateY(-1px);
        }

        .select:hover {
            border-color: #cbd5e1;
        }

        /* Badge Components - 匹配现代设计的徽章样式 */
        .badge {
            display: inline-flex;
            align-items: center;
            border-radius: 9999px;
            padding: 0.375rem 0.875rem;
            font-size: 0.75rem;
            font-weight: 700;
            letter-spacing: 0.025em;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
            transition: all 200ms ease;
        }

        .badge-default {
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
            color: white;
        }

        .badge-secondary {
            background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
            color: #475569;
            border: 1px solid #cbd5e1;
        }

        .badge-destructive {
            background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
            color: white;
        }

        .badge-success {
            background: linear-gradient(135deg, #10b981 0%, #059669 100%);
            color: white;
        }

        .badge-warning {
            background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
            color: white;
        }

        .badge-outline {
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(10px);
            color: #475569;
            border: 2px solid #e2e8f0;
        }

        /* Layout Grid */
        .grid {
            display: grid;
            gap: 1.5rem;
        }

        .grid-cols-1 {
            grid-template-columns: repeat(1, minmax(0, 1fr));
        }

        .grid-cols-2 {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }

        .grid-cols-3 {
            grid-template-columns: repeat(3, minmax(0, 1fr));
        }

        /* Specific Layout */
        .main-grid {
            display: grid;
            grid-template-columns: 1fr 400px;
            gap: 2rem;
            align-items: start;
        }

        /* Controls Panel */
        .controls-panel {
            display: flex;
            flex-direction: column;
            gap: 1rem;
            margin-bottom: 2rem;
        }

        .search-container {
            position: relative;
        }

        .search-icon {
            position: absolute;
            left: 0.75rem;
            top: 50%;
            transform: translateY(-50%);
            color: hsl(var(--muted-foreground));
            width: 1rem;
            height: 1rem;
        }

        .search-input {
            padding-left: 2.5rem;
        }

        .controls-row {
            display: flex;
            gap: 1rem;
            align-items: center;
        }

        .view-toggle {
            display: flex;
            border: 1px solid hsl(var(--border));
            border-radius: var(--radius);
            overflow: hidden;
        }

        .view-btn {
            padding: 0.5rem;
            border: none;
            background: transparent;
            cursor: pointer;
            transition: all 150ms ease-in-out;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .view-btn.active {
            background-color: hsl(var(--primary));
            color: hsl(var(--primary-foreground));
        }

        .view-btn:not(.active):hover {
            background-color: hsl(var(--muted));
        }

        /* Data List */
        .data-list {
            height: fit-content;
        }

        .list-content {
            max-height: 600px;
            overflow-y: auto;
        }

        .data-item {
            padding: 1.5rem;
            border-bottom: 1px solid hsl(var(--border));
            cursor: pointer;
            transition: all 150ms ease-in-out;
            position: relative;
        }

        .data-item:last-child {
            border-bottom: none;
        }

        .data-item:hover {
            background-color: hsl(var(--muted) / 0.5);
        }

        .data-item.selected {
            background-color: hsl(var(--primary) / 0.1);
            border-left: 3px solid hsl(var(--primary));
        }

        .item-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 0.75rem;
        }

        .item-title {
            font-size: 1.125rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
        }

        .item-meta {
            display: flex;
            flex-wrap: wrap;
            gap: 1rem;
            color: hsl(var(--muted-foreground));
            font-size: 0.875rem;
        }

        .meta-item {
            display: flex;
            align-items: center;
            gap: 0.375rem;
        }

        .meta-icon {
            width: 0.875rem;
            height: 0.875rem;
        }

        /* Report Panel */
        .report-panel {
            position: sticky;
            top: 1.5rem;
        }

        .selected-file-info {
            background-color: hsl(var(--muted) / 0.5);
            border-radius: var(--radius);
            padding: 1rem;
            margin-bottom: 1.5rem;
            border: 1px solid hsl(var(--border));
        }

        .selected-file-info.empty {
            text-align: center;
            color: hsl(var(--muted-foreground));
            padding: 2rem 1rem;
        }

        .file-name {
            font-weight: 600;
            margin-bottom: 0.5rem;
        }

        .file-details {
            font-size: 0.875rem;
            color: hsl(var(--muted-foreground));
            line-height: 1.5;
        }

        .format-buttons {
            display: flex;
            flex-direction: column;
            gap: 0.75rem;
        }

        .format-btn {
            justify-content: flex-start;
            padding: 1rem;
            height: auto;
            position: relative;
        }

        .format-btn.loading::after {
            content: '';
            position: absolute;
            right: 1rem;
            top: 50%;
            transform: translateY(-50%);
            width: 1rem;
            height: 1rem;
            border: 2px solid hsl(var(--muted-foreground));
            border-radius: 50%;
            border-top-color: hsl(var(--primary));
            animation: spin 1s linear infinite;
        }

        /* Empty State */
        .empty-state {
            text-align: center;
            padding: 3rem 2rem;
            color: hsl(var(--muted-foreground));
        }

        .empty-icon {
            width: 3rem;
            height: 3rem;
            margin: 0 auto 1rem;
            opacity: 0.5;
        }

        /* Animations */
        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(10px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .fade-in {
            animation: fadeIn 0.3s ease-out;
        }

        /* Responsive Design */
        @media (max-width: 1024px) {
            .main-grid {
                grid-template-columns: 1fr;
                gap: 1.5rem;
            }

            .report-panel {
                position: static;
            }
        }

        @media (max-width: 768px) {
            .container {
                padding: 1rem;
            }

            .page-title {
                font-size: 1.875rem;
                flex-direction: column;
                gap: 0.5rem;
                text-align: center;
            }

            .controls-row {
                flex-direction: column;
                align-items: stretch;
            }

            .view-toggle {
                width: 100%;
            }

            .view-btn {
                flex: 1;
            }
        }

        /* Progress Modal - 居中弹窗进度条 */
        .progress-modal {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(8px);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s ease-in-out;
        }

        .progress-modal.show {
            opacity: 1;
            visibility: visible;
        }

        .progress-content {
            background: hsl(var(--card));
            border: 1px solid hsl(var(--border));
            border-radius: calc(var(--radius) + 4px);
            padding: 2rem;
            min-width: 400px;
            max-width: 500px;
            box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 10px 10px -5px rgb(0 0 0 / 0.04);
            transform: scale(0.95);
            transition: transform 0.3s ease-in-out;
        }

        .progress-modal.show .progress-content {
            transform: scale(1);
        }

        .progress-header {
            text-align: center;
            margin-bottom: 1.5rem;
        }

        .progress-title {
            font-size: 1.25rem;
            font-weight: 600;
            color: hsl(var(--foreground));
            margin-bottom: 0.5rem;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
        }

        .progress-description {
            color: hsl(var(--muted-foreground));
            font-size: 0.875rem;
        }

        .progress-bar-container {
            margin-bottom: 1.5rem;
        }

        .progress-bar {
            width: 100%;
            height: 8px;
            background: hsl(var(--muted));
            border-radius: 9999px;
            overflow: hidden;
            margin-bottom: 0.75rem;
        }

        .progress-bar-fill {
            height: 100%;
            background: linear-gradient(90deg, #6366f1, #8b5cf6, #06b6d4);
            background-size: 200% 100%;
            border-radius: 9999px;
            transition: width 0.5s ease-in-out;
            animation: progressShimmer 2s linear infinite;
        }

        @keyframes progressShimmer {
            0% {
                background-position: 200% 0;
            }

            100% {
                background-position: -200% 0;
            }
        }

        .progress-text {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 0.875rem;
            color: hsl(var(--muted-foreground));
        }

        .progress-steps {
            margin-top: 1rem;
        }

        .progress-step {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            padding: 0.5rem 0;
            font-size: 0.875rem;
            color: hsl(var(--muted-foreground));
            transition: color 0.3s ease;
        }

        .progress-step.active {
            color: hsl(var(--primary));
        }

        .progress-step.completed {
            color: hsl(var(--success));
        }

        .progress-step-icon {
            width: 1rem;
            height: 1rem;
            border-radius: 50%;
            border: 2px solid hsl(var(--border));
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s ease;
        }

        .progress-step.active .progress-step-icon {
            border-color: hsl(var(--primary));
            background: hsl(var(--primary));
        }

        .progress-step.completed .progress-step-icon {
            border-color: hsl(var(--success));
            background: hsl(var(--success));
        }

        .progress-step-spinner {
            width: 0.75rem;
            height: 0.75rem;
            border: 2px solid transparent;
            border-top: 2px solid hsl(var(--primary-foreground));
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        .progress-step-check {
            width: 0.75rem;
            height: 0.75rem;
            color: hsl(var(--success-foreground));
        }

        /* Success/Error States */
        .progress-success {
            text-align: center;
            color: hsl(var(--success));
        }

        .progress-error {
            text-align: center;
            color: hsl(var(--destructive));
        }

        .progress-actions {
            display: flex;
            gap: 0.75rem;
            justify-content: center;
            margin-top: 1.5rem;
        }

        /* Floating particles animation */
        .floating-particles {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            pointer-events: none;
            z-index: -1;
        }

        .particle {
            position: absolute;
            width: 4px;
            height: 4px;
            background: rgba(99, 102, 241, 0.3);
            border-radius: 50%;
            animation: float 6s ease-in-out infinite;
        }

        .particle:nth-child(2) {
            background: rgba(139, 92, 246, 0.3);
            animation-delay: -2s;
            animation-duration: 8s;
        }

        .particle:nth-child(3) {
            background: rgba(59, 130, 246, 0.3);
            animation-delay: -4s;
            animation-duration: 7s;
        }

        @keyframes float {

            0%,
            100% {
                transform: translateY(0px) rotate(0deg);
                opacity: 0;
            }

            10% {
                opacity: 1;
            }

            90% {
                opacity: 1;
            }

            50% {
                transform: translateY(-100px) rotate(180deg);
            }
        }

        /* Utility Classes */
        .flex {
            display: flex;
        }

        .items-center {
            align-items: center;
        }

        .justify-between {
            justify-content: space-between;
        }

        .gap-2 {
            gap: 0.5rem;
        }

        .gap-4 {
            gap: 1rem;
        }

        .mb-4 {
            margin-bottom: 1rem;
        }

        .text-sm {
            font-size: 0.875rem;
        }

        .text-muted {
            color: hsl(var(--muted-foreground));
        }

        .font-medium {
            font-weight: 500;
        }

        .font-semibold {
            font-weight: 600;
        }
    </style>
</head>

<body>
    <!-- 背景装饰网格 -->
    <div class="bg-grid"></div>

    <!-- 浮动粒子效果 -->
    <div class="floating-particles">
        <div class="particle" style="top: 20%; left: 10%;"></div>
        <div class="particle" style="top: 60%; left: 80%;"></div>
        <div class="particle" style="top: 40%; left: 60%;"></div>
    </div>

    <!-- 进度弹窗 -->
    <div class="progress-modal" id="progressModal">
        <div class="progress-content">
            <div class="progress-header">
                <div class="progress-title">
                    <i data-lucide="file-text"></i>
                    <span id="progressTitle">正在生成报告</span>
                </div>
                <div class="progress-description" id="progressDescription">
                    请稍候，我们正在为您生成安全审计报告...
                </div>
            </div>

            <div class="progress-bar-container">
                <div class="progress-bar">
                    <div class="progress-bar-fill" id="progressBarFill" style="width: 0%"></div>
                </div>
                <div class="progress-text">
                    <span id="progressText">准备中...</span>
                    <span id="progressPercent">0%</span>
                </div>
            </div>

            <div class="progress-steps" id="progressSteps">
                <div class="progress-step" id="step-1">
                    <div class="progress-step-icon">
                        <div class="progress-step-spinner"></div>
                    </div>
                    <span>解析数据文件</span>
                </div>
                <div class="progress-step" id="step-2">
                    <div class="progress-step-icon"></div>
                    <span>生成报告内容</span>
                </div>
                <div class="progress-step" id="step-3">
                    <div class="progress-step-icon"></div>
                    <span>格式化输出</span>
                </div>
                <div class="progress-step" id="step-4">
                    <div class="progress-step-icon"></div>
                    <span>完成生成</span>
                </div>
            </div>

            <div class="progress-actions" id="progressActions" style="display: none;">
                <button class="btn btn-primary" id="downloadBtn" style="display: none;">
                    <i data-lucide="download"></i>
                    下载报告
                </button>
                <button class="btn btn-outline" onclick="closeProgressModal()">
                    关闭
                </button>
            </div>
        </div>
    </div>

    <div class="container">
        <!-- Page Header -->
        <div class="page-header">
            <h1 class="page-title">
                <i data-lucide="shield-check"></i>
                AuditLuma 报告生成器
            </h1>
            <p class="page-description">智能安全审计报告生成，支持多种格式导出</p>
        </div>

        <!-- Controls Panel -->
        <div class="controls-panel">
            <div class="search-container">
                <i data-lucide="search" class="search-icon"></i>
                <input type="text" class="input search-input" id="searchInput" placeholder="搜索项目名称、时间或漏洞信息..."
                    autocomplete="off">
            </div>

            <div class="controls-row">
                <select class="select" id="sortSelect" style="flex: 1;">
                    <option value="time-desc">按时间排序 (最新)</option>
                    <option value="time-asc">按时间排序 (最旧)</option>
                    <option value="name-asc">按名称排序 (A-Z)</option>
                    <option value="name-desc">按名称排序 (Z-A)</option>
                    <option value="vuln-desc">按漏洞数排序 (高-低)</option>
                    <option value="vuln-asc">按漏洞数排序 (低-高)</option>
                </select>

                <div class="view-toggle">
                    <button class="view-btn active" data-view="list">
                        <i data-lucide="list"></i>
                    </button>
                    <button class="view-btn" data-view="grid">
                        <i data-lucide="grid-3x3"></i>
                    </button>
                </div>
            </div>
        </div>

        <!-- Main Content -->
        <div class="main-grid">
            <!-- Data List -->
            <div class="card data-list">
                <div class="card-header">
                    <h3 class="card-title">
                        <i data-lucide="database"></i>
                        历史分析数据
                        <span id="resultCount" class="text-sm text-muted font-medium"></span>
                    </h3>
                </div>
                <div class="list-content" id="dataList">
                    <!-- Data items will be loaded here -->
                </div>
            </div>

            <!-- Report Generation Panel -->
            <div class="card report-panel">
                <div class="card-header">
                    <h4 class="card-title">
                        <i data-lucide="file-text"></i>
                        生成报告
                    </h4>
                </div>
                <div class="card-content">
                    <div class="selected-file-info empty" id="selectedFileInfo">
                        <i data-lucide="mouse-pointer"
                            style="width: 2rem; height: 2rem; margin-bottom: 0.5rem; opacity: 0.5;"></i>
                        <p>请选择左侧的分析数据</p>
                    </div>

                    <div class="format-buttons">
                        <button class="btn btn-outline format-btn" id="btn-txt" disabled
                            onclick="generateReport('txt')">
                            <i data-lucide="file-text"></i>
                            <span>TXT 报告</span>
                        </button>
                        <button class="btn btn-outline format-btn" id="btn-json" disabled
                            onclick="generateReport('json')">
                            <i data-lucide="code"></i>
                            <span>JSON 报告</span>
                        </button>
                        <button class="btn btn-outline format-btn" id="btn-excel" disabled
                            onclick="generateReport('excel')">
                            <i data-lucide="table"></i>
                            <span>Excel 报告</span>
                        </button>
                        <button class="btn btn-outline format-btn" id="btn-html" disabled
                            onclick="generateReport('html')">
                            <i data-lucide="globe"></i>
                            <span>HTML 报告</span>
                        </button>
                        <button class="btn btn-outline format-btn" id="btn-pdf" disabled
                            onclick="generateReport('pdf')">
                            <i data-lucide="file"></i>
                            <span>PDF 报告</span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // Initialize Lucide icons
        lucide.createIcons();

        class ReportGenerator {
            constructor() {
                this.allData = [];
                this.filteredData = [];
                this.selectedFile = null;
                this.currentSort = 'time-desc';
                this.currentView = 'list';

                this.init();
            }

            init() {
                this.bindEvents();
                this.loadData();
            }

            bindEvents() {
                // Search input
                document.getElementById('searchInput').addEventListener('input', (e) => {
                    this.handleSearch(e.target.value);
                });

                // Sort select
                document.getElementById('sortSelect').addEventListener('change', (e) => {
                    this.currentSort = e.target.value;
                    this.sortAndRender();
                });

                // View toggle
                document.querySelectorAll('.view-btn').forEach(btn => {
                    btn.addEventListener('click', (e) => {
                        this.toggleView(e.currentTarget.dataset.view);
                    });
                });
            }

            async loadData() {
                try {
                    // Show loading skeleton
                    this.showLoadingSkeleton();

                    const response = await fetch('/api/history');
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const data = await response.json();
                    this.allData = Array.isArray(data) ? data : [];
                    this.filteredData = [...this.allData];
                    this.sortAndRender();
                } catch (error) {
                    console.error('Error loading data:', error);
                    this.showError('加载数据失败，请检查网络连接或刷新页面重试');
                }
            }

            showLoadingSkeleton() {
                const container = document.getElementById('dataList');
                container.innerHTML = Array(5).fill(0).map(() => `
                    <div class="data-item">
                        <div class="item-header">
                            <div style="flex: 1;">
                                <div style="height: 1.25rem; background: hsl(var(--muted)); border-radius: 4px; margin-bottom: 0.5rem; width: 70%;"></div>
                                <div style="height: 1rem; background: hsl(var(--muted)); border-radius: 4px; width: 50%;"></div>
                            </div>
                            <div style="width: 3rem; height: 1.5rem; background: hsl(var(--muted)); border-radius: 9999px;"></div>
                        </div>
                    </div>
                `).join('');
            }

            handleSearch(query) {
                if (!query.trim()) {
                    this.filteredData = [...this.allData];
                } else {
                    const searchTerm = query.toLowerCase();
                    this.filteredData = this.allData.filter(item =>
                        (item.display_name || '').toLowerCase().includes(searchTerm) ||
                        (item.project_name || '').toLowerCase().includes(searchTerm) ||
                        (item.analysis_time || '').toLowerCase().includes(searchTerm) ||
                        (item.vulnerabilities_count || 0).toString().includes(searchTerm)
                    );
                }
                this.sortAndRender();
            }

            sortAndRender() {
                this.sortData();
                this.renderDataList();
                this.updateResultCount();
            }

            sortData() {
                this.filteredData.sort((a, b) => {
                    switch (this.currentSort) {
                        case 'time-desc':
                            return new Date(b.analysis_time || 0) - new Date(a.analysis_time || 0);
                        case 'time-asc':
                            return new Date(a.analysis_time || 0) - new Date(b.analysis_time || 0);
                        case 'name-asc':
                            return (a.display_name || '').localeCompare(b.display_name || '');
                        case 'name-desc':
                            return (b.display_name || '').localeCompare(a.display_name || '');
                        case 'vuln-desc':
                            return (b.vulnerabilities_count || 0) - (a.vulnerabilities_count || 0);
                        case 'vuln-asc':
                            return (a.vulnerabilities_count || 0) - (b.vulnerabilities_count || 0);
                        default:
                            return 0;
                    }
                });
            }

            renderDataList() {
                const container = document.getElementById('dataList');

                if (this.filteredData.length === 0) {
                    container.innerHTML = `
                        <div class="empty-state">
                            <i data-lucide="search" class="empty-icon"></i>
                            <p>没有找到匹配的数据</p>
                        </div>
                    `;
                    lucide.createIcons();
                    return;
                }

                container.innerHTML = this.filteredData.map(item => {
                    const vulnerabilityLevel = this.getVulnerabilityLevel(item.vulnerabilities_count || 0);

                    return `
                        <div class="data-item fade-in" onclick="reportGenerator.selectFile('${item.filename || item.id}', this)" data-filename="${item.filename || item.id}">
                            <div class="item-header">
                                <div style="flex: 1;">
                                    <div class="item-title">${this.escapeHtml(item.display_name || item.title || '未命名项目')}</div>
                                    <div class="item-meta">
                                        <div class="meta-item">
                                            <i data-lucide="clock" class="meta-icon"></i>
                                            <span>${this.formatDate(item.analysis_time || item.createdAt)}</span>
                                        </div>
                                        <div class="meta-item">
                                            <i data-lucide="folder" class="meta-icon"></i>
                                            <span>${this.escapeHtml(item.project_name || '未知项目')}</span>
                                        </div>
                                        <div class="meta-item">
                                            <i data-lucide="file" class="meta-icon"></i>
                                            <span>${item.scanned_files || 0} 个文件</span>
                                        </div>
                                    </div>
                                </div>
                                <span class="badge ${vulnerabilityLevel}">
                                    ${item.vulnerabilities_count || 0}
                                </span>
                            </div>
                        </div>
                    `;
                }).join('');

                lucide.createIcons();
            }

            getVulnerabilityLevel(count) {
                if (count >= 10) return 'badge-destructive';
                if (count >= 5) return 'badge-warning';
                if (count > 0) return 'badge-success';
                return 'badge-secondary';
            }

            updateResultCount() {
                const countElement = document.getElementById('resultCount');
                const total = this.allData.length;
                const filtered = this.filteredData.length;

                if (filtered === total) {
                    countElement.textContent = `(${total} 项)`;
                } else {
                    countElement.textContent = `(${filtered}/${total} 项)`;
                }
            }

            selectFile(filename, element) {
                // Remove previous selection
                document.querySelectorAll('.data-item').forEach(item => {
                    item.classList.remove('selected');
                });

                // Add selection to current item
                element.classList.add('selected');

                // Find selected file data
                const fileData = this.allData.find(item => (item.filename || item.id) === filename);
                if (!fileData) return;

                this.selectedFile = filename;
                this.updateSelectedFileInfo(fileData);
                this.enableReportButtons();
            }

            updateSelectedFileInfo(fileData) {
                const container = document.getElementById('selectedFileInfo');
                container.className = 'selected-file-info';
                container.innerHTML = `
                    <div class="file-name">${this.escapeHtml(fileData.display_name || fileData.title || '未命名项目')}</div>
                    <div class="file-details">
                        <div>项目: ${this.escapeHtml(fileData.project_name || '未知项目')}</div>
                        <div>时间: ${this.formatDate(fileData.analysis_time || fileData.createdAt)}</div>
                        <div>漏洞: ${fileData.vulnerabilities_count || 0} 个</div>
                        <div>文件: ${fileData.scanned_files || 0} 个</div>
                    </div>
                `;
            }

            enableReportButtons() {
                ['txt', 'json', 'excel', 'html', 'pdf'].forEach(format => {
                    const btn = document.getElementById(`btn-${format}`);
                    if (btn) {
                        btn.disabled = false;
                    }
                });
            }

            toggleView(view) {
                // Update button states
                document.querySelectorAll('.view-btn').forEach(btn => {
                    btn.classList.toggle('active', btn.dataset.view === view);
                });

                this.currentView = view;
                // View toggle functionality can be extended here
            }

            async generateReport(format) {
                if (!this.selectedFile) {
                    this.showNotification('请先选择分析数据文件', 'warning');
                    return;
                }

                // 显示进度弹窗
                this.showProgressModal(format);

                // 禁用所有按钮
                this.disableAllButtons();

                try {
                    // 模拟进度步骤
                    await this.simulateProgress();

                    const response = await fetch('/api/generate-report', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            data_file: this.selectedFile,
                            format: format
                        })
                    });

                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const result = await response.json();

                    if (result.success) {
                        this.showProgressSuccess(result, format);
                    } else {
                        this.showProgressError(result.error || '未知错误');
                    }
                } catch (error) {
                    console.error('Error generating report:', error);
                    this.showProgressError('生成报告时发生错误，请重试');
                } finally {
                    // 恢复按钮状态
                    this.enableAllButtons();
                }
            }

            showProgressModal(format) {
                const modal = document.getElementById('progressModal');
                const title = document.getElementById('progressTitle');
                const description = document.getElementById('progressDescription');

                title.textContent = `正在生成 ${format.toUpperCase()} 报告`;
                description.textContent = '请稍候，我们正在为您生成安全审计报告...';

                // 重置进度状态
                this.resetProgressModal();

                modal.classList.add('show');
                lucide.createIcons();
            }

            resetProgressModal() {
                // 重置进度条
                document.getElementById('progressBarFill').style.width = '0%';
                document.getElementById('progressText').textContent = '准备中...';
                document.getElementById('progressPercent').textContent = '0%';

                // 重置所有步骤
                ['step-1', 'step-2', 'step-3', 'step-4'].forEach(stepId => {
                    const step = document.getElementById(stepId);
                    step.classList.remove('active', 'completed');
                    step.querySelector('.progress-step-icon').innerHTML = '';
                });

                // 隐藏操作按钮
                document.getElementById('progressActions').style.display = 'none';
                document.getElementById('downloadBtn').style.display = 'none';
            }

            async simulateProgress() {
                const steps = [
                    { id: 'step-1', text: '解析数据文件', progress: 25 },
                    { id: 'step-2', text: '生成报告内容', progress: 50 },
                    { id: 'step-3', text: '格式化输出', progress: 75 },
                    { id: 'step-4', text: '完成生成', progress: 100 }
                ];

                for (let i = 0; i < steps.length; i++) {
                    const step = steps[i];

                    // 更新进度条
                    this.updateProgress(step.progress, step.text);

                    // 更新步骤状态
                    this.updateStepStatus(step.id, 'active');

                    // 等待一段时间模拟处理
                    await new Promise(resolve => setTimeout(resolve, 800 + Math.random() * 400));

                    // 完成当前步骤
                    this.updateStepStatus(step.id, 'completed');
                }
            }

            updateProgress(percent, text) {
                const progressBar = document.getElementById('progressBarFill');
                const progressText = document.getElementById('progressText');
                const progressPercent = document.getElementById('progressPercent');

                progressBar.style.width = `${percent}%`;
                progressText.textContent = text;
                progressPercent.textContent = `${percent}%`;
            }

            updateStepStatus(stepId, status) {
                const step = document.getElementById(stepId);
                const icon = step.querySelector('.progress-step-icon');

                // 清除之前的状态
                step.classList.remove('active', 'completed');

                if (status === 'active') {
                    step.classList.add('active');
                    icon.innerHTML = '<div class="progress-step-spinner"></div>';
                } else if (status === 'completed') {
                    step.classList.add('completed');
                    icon.innerHTML = '<i data-lucide="check" class="progress-step-check"></i>';
                    lucide.createIcons();
                }
            }

            showProgressSuccess(result, format) {
                const title = document.getElementById('progressTitle');
                const description = document.getElementById('progressDescription');
                const actions = document.getElementById('progressActions');
                const downloadBtn = document.getElementById('downloadBtn');

                title.innerHTML = '<i data-lucide="check-circle"></i> 报告生成成功！';
                description.textContent = `${format.toUpperCase()} 格式报告已生成完成`;

                actions.style.display = 'flex';

                if (result.download_url) {
                    downloadBtn.style.display = 'inline-flex';
                    downloadBtn.onclick = () => {
                        const link = document.createElement('a');
                        link.href = result.download_url;
                        link.download = result.filename || `report.${format}`;
                        document.body.appendChild(link);
                        link.click();
                        document.body.removeChild(link);
                    };
                }

                lucide.createIcons();
            }

            showProgressError(error) {
                const title = document.getElementById('progressTitle');
                const description = document.getElementById('progressDescription');
                const actions = document.getElementById('progressActions');

                title.innerHTML = '<i data-lucide="x-circle"></i> 生成失败';
                description.textContent = error;
                actions.style.display = 'flex';

                lucide.createIcons();
            }

            disableAllButtons() {
                ['txt', 'json', 'excel', 'html', 'pdf'].forEach(format => {
                    const btn = document.getElementById(`btn-${format}`);
                    if (btn) {
                        btn.disabled = true;
                    }
                });
            }

            enableAllButtons() {
                if (this.selectedFile) {
                    ['txt', 'json', 'excel', 'html', 'pdf'].forEach(format => {
                        const btn = document.getElementById(`btn-${format}`);
                        if (btn) {
                            btn.disabled = false;
                        }
                    });
                }
            }

            showNotification(message, type = 'info') {
                // Create a simple toast notification
                const toast = document.createElement('div');
                toast.className = `notification ${type}`;
                toast.style.cssText = `
                    position: fixed;
                    top: 1rem;
                    right: 1rem;
                    background: hsl(var(--card));
                    border: 1px solid hsl(var(--border));
                    border-radius: var(--radius);
                    padding: 1rem;
                    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
                    z-index: 1000;
                    max-width: 400px;
                    transform: translateX(100%);
                    transition: transform 0.3s ease-in-out;
                `;

                if (type === 'success') {
                    toast.style.borderColor = 'hsl(var(--success))';
                    toast.style.backgroundColor = 'hsl(var(--success) / 0.1)';
                } else if (type === 'error') {
                    toast.style.borderColor = 'hsl(var(--destructive))';
                    toast.style.backgroundColor = 'hsl(var(--destructive) / 0.1)';
                } else if (type === 'warning') {
                    toast.style.borderColor = 'hsl(var(--warning))';
                    toast.style.backgroundColor = 'hsl(var(--warning) / 0.1)';
                }

                toast.textContent = message;
                document.body.appendChild(toast);

                // Animate in
                setTimeout(() => {
                    toast.style.transform = 'translateX(0)';
                }, 10);

                // Auto remove after 5 seconds
                setTimeout(() => {
                    toast.style.transform = 'translateX(100%)';
                    setTimeout(() => {
                        if (toast.parentNode) {
                            document.body.removeChild(toast);
                        }
                    }, 300);
                }, 5000);
            }

            showError(message) {
                const container = document.getElementById('dataList');
                container.innerHTML = `
                    <div class="empty-state">
                        <i data-lucide="alert-triangle" class="empty-icon" style="color: hsl(var(--destructive));"></i>
                        <p>${message}</p>
                    </div>
                `;
                lucide.createIcons();
            }

            formatDate(dateString) {
                if (!dateString) return '未知时间';
                try {
                    const date = new Date(dateString);
                    return date.toLocaleString('zh-CN', {
                        year: 'numeric',
                        month: '2-digit',
                        day: '2-digit',
                        hour: '2-digit',
                        minute: '2-digit'
                    });
                } catch (error) {
                    return dateString;
                }
            }

            escapeHtml(text) {
                const div = document.createElement('div');
                div.textContent = text || '';
                return div.innerHTML;
            }
        }

        // Initialize the report generator
        const reportGenerator = new ReportGenerator();

        // Global function for onclick handlers
        function generateReport(format) {
            reportGenerator.generateReport(format);
        }

        // Global function to close progress modal
        function closeProgressModal() {
            const modal = document.getElementById('progressModal');
            modal.classList.remove('show');
        }
    </script>
</body>

</html>